/**************************************************************************
	FSHOME - Curtains Handle Node - Bridge eth-485
	Architecture reference:
	|-"eth-" SoulissApp
	|-"eth-" R1B1 Gateway -" R1B2Peer -" R1B4Peer -" R1B4Peer
	|-"eth-" R2B1 Bridge -" R2B2Peer -" R2B3Peer -" R2B4Peer
	|-"eth-" R3B1 Bridge -" R3B2Peer -" R3B3Peer -" R3B4Peer
	|-"eth-" R4B1 Bridge -" R4B2Peer -" R4B3Peer -" R4B4Peer
***************************************************************************/
// Define the boards that we want program in order to create the appropriate sketch.
#define	R1B1	1

#include "fshSoulissNetwork.h"
#include "fshUniBoardsSetup_v0.h"

#if(UNB_DINO_GATEWAY)
	#include "bconf/DINo_v2_Gateway_RS485.h"
#endif
#if(UNB_DINO_BRIDGE)
	#include "bconf/DINo_v2_PeerBridge_RS485.h"
#endif
#if(UNB_DINO_PEER)
	#include "bconf/DINo_v2_Peer_RS485.h"
#endif

//#define SKETCH_DEBUG 1
#ifdef SKETCH_DEBUG
#define VNET_DEBUG_INSKETCH
#define VNET_DEBUG    1
#define MaCaco_DEBUG_INSKETCH
#define MaCaco_DEBUG  1
#endif

#include "fshSoulissCommon.h"
#include "Souliss.h"
#include "SpeakEasy.h"
#include "SPI.h"

// Include DINO HW common definitions
#include "DINo_v2_HW_Setup.h"			// standard board hw configuration

#if(UNB_DS18B20SUPPORT)
	#include <OneWire.h>
	#include <DallasTemperature.h>
#endif

#if(UNB_CURTAINS_TYPE)
	// SLOT definitions
	#define CURTAIN_1_SLOT		0
	#define CURTAIN_2_SLOT		1
#endif	
#if(UNB_CURTAINS_TYPE && UNB_DS18B20SUPPORT)
	#define TEMPERATURE_SLOT	2
#endif	

#if(UNB_LIGHTS_TYPE)
	// SLOT definitions
	#define RELAY1			0
	#define RELAY2			1
	#define RELAY3			2
	#define RELAY4			3
#endif	
#if(UNB_LIGHTS_TYPE && UNB_DS18B20SUPPORT)
	#define TEMPERATURE_SLOT	4
#endif	

// Global Variables
#if(UNB_DINO_GATEWAY || UNB_DINO_BRIDGE)
	// Network address
	uint8_t ip_address[4]  = {IP_ADDRESS_1, IP_ADDRESS_2, IP_ADDRESS_3, IP_ADDRESS_4};
  uint8_t subnet_mask[4] = {255, 255, 255, 0};
  uint8_t ip_gateway[4]  = {IP_ADDRESS_1, IP_ADDRESS_2, IP_ADDRESS_3, IP_ADDRESS_4_NETGW};
#endif

#if(UNB_DS18B20SUPPORT && !SKETCH_DEBUG)
	bool ds18b20_RequestPhase = true;

	// Setup oneWire instance to handle the DS18B20 sensor
	OneWire oneWire(DINOII_1WIRE_BUS);
	DallasTemperature sensors(&oneWire);
#endif

void setup()
{
	#ifdef SKETCH_DEBUG
	Serial.begin(9600);
	#endif

	// Init the board
	DINo_v2_HW_Setup();
#if(UNB_DINO_PEER)
	digitalWrite(9, HIGH);
#endif
	
	// Setup network configuration
#if(UNB_DINO_GATEWAY || UNB_DINO_BRIDGE)
	Souliss_SetIPAddress(ip_address, subnet_mask, ip_gateway);
#endif

	// Set the 485 address
#if(UNB_DINO_GATEWAY)
	Souliss_SetAddress(RS485_ADDRESS, SOULISS_SUBNET_MASK, SOULISS_SUPERNODE);
	SetAsGateway(IP_ADDRESS_4);
#else
	Souliss_SetAddress(RS485_ADDRESS, SOULISS_SUBNET_MASK, RS485_ADDRESS_R1B1);         
#endif

	// Set Up the slots
#if(UNB_CURTAINS_TYPE)
	Souliss_SetT22(memory_map, CURTAIN_1_SLOT);
	Souliss_SetT22(memory_map, CURTAIN_2_SLOT);
#endif
#if(UNB_LIGHTS_TYPE)
	Souliss_SetT11(memory_map, RELAY1);
	Souliss_SetT11(memory_map, RELAY2);
	Souliss_SetT11(memory_map, RELAY3);
	Souliss_SetT11(memory_map, RELAY4);
#endif

#if(UNB_DS18B20SUPPORT && !SKETCH_DEBUG)
	Set_Temperature(TEMPERATURE_SLOT);

	// Start up the DallasTemperature library
	sensors.setWaitForConversion(false);
	sensors.setResolution(12);
	sensors.begin();
#endif	
} 

void loop()
{ 
	EXECUTEFAST() {						
		UPDATEFAST();	
		
		FAST_50ms() {
		
#if(UNB_CURTAINS_TYPE)
			// Use OPEN and CLOSE Commands
			Souliss_DigIn(IN1, Souliss_T2n_OpenCmd, memory_map, CURTAIN_1_SLOT);
			Souliss_DigIn(IN2, Souliss_T2n_CloseCmd, memory_map, CURTAIN_1_SLOT);
			Souliss_DigIn(IN3, Souliss_T2n_OpenCmd, memory_map, CURTAIN_2_SLOT);
			Souliss_DigIn(IN4, Souliss_T2n_CloseCmd, memory_map, CURTAIN_2_SLOT);
		
			// Run the logic
			Souliss_Logic_T22(memory_map, CURTAIN_1_SLOT, &data_changed);
			Souliss_Logic_T22(memory_map, CURTAIN_2_SLOT, &data_changed);
			
			// Act on outputs, the Stop command is defined as Open | Close and active both the outputs
			Souliss_DigOut(OUT1, Souliss_T2n_Coil_Open, memory_map, CURTAIN_1_SLOT);	
			Souliss_DigOut(OUT2, Souliss_T2n_Coil_Close, memory_map, CURTAIN_1_SLOT);	
			Souliss_DigOut(OUT3, Souliss_T2n_Coil_Open, memory_map, CURTAIN_2_SLOT);	
			Souliss_DigOut(OUT4, Souliss_T2n_Coil_Close, memory_map, CURTAIN_2_SLOT);	
#endif
#if(UNB_LIGHTS_TYPE)
			ssDigIn(IN1, Souliss_T1n_ToogleCmd, RELAY1);
			ssDigIn(IN2, Souliss_T1n_ToogleCmd, RELAY2);
			ssDigIn(IN3, Souliss_T1n_ToogleCmd, RELAY3);
			ssDigIn(IN4, Souliss_T1n_ToogleCmd, RELAY4);
		
			Souliss_Logic_T11(memory_map, RELAY1, &data_changed);
			Souliss_Logic_T11(memory_map, RELAY2, &data_changed);
			Souliss_Logic_T11(memory_map, RELAY3, &data_changed);
			Souliss_Logic_T11(memory_map, RELAY4, &data_changed);
			
			ssDigOut(OUT1, Souliss_T1n_Coil, RELAY1);
			ssDigOut(OUT2, Souliss_T1n_Coil, RELAY2);
			ssDigOut(OUT3, Souliss_T1n_Coil, RELAY3);
			ssDigOut(OUT4, Souliss_T1n_Coil, RELAY4);
#endif
		} 
		
		// Here we process all communication with other nodes
#if(UNB_DINO_GATEWAY)
		FAST_GatewayComms();		
#endif		
#if(UNB_DINO_BRIDGE || UNB_DINO_PEER)
		FAST_PeerComms();

		// At first runs, we look for a gateway to join
		START_PeerJoin();
		
		// Periodically check if the peer node has joined the gateway
		FAST_1110ms() {
			if(JoinInProgress())	// If join is in progress, toogle the LED at every turn
				ToogleLED();
			else
				TurnOnLED();		// Once completed, turn ON
		}		
#endif		
	}
	
	EXECUTESLOW() {	
		UPDATESLOW();

#if(UNB_DINO_BRIDGE || UNB_DINO_PEER)
		// Here we periodically check for a gateway to join
		SLOW_PeerJoin();		
#endif

		SLOW_10s() {
#if(UNB_CURTAINS_TYPE)
			Timer_Windows(CURTAIN_1_SLOT);
			Timer_Windows(CURTAIN_2_SLOT);	
#endif			
#if(UNB_LIGHTS_TYPE)
			Souliss_T11_Timer(memory_map, RELAY1);
			Souliss_T11_Timer(memory_map, RELAY2);
			Souliss_T11_Timer(memory_map, RELAY3);
			Souliss_T11_Timer(memory_map, RELAY4);
#endif
		} 	  

#if(UNB_DS18B20SUPPORT && !SKETCH_DEBUG)
		SLOW_50s() { 
			TurnOffLED();
			if(ds18b20_RequestPhase) {
			  sensors.requestTemperatures(); // Send the command to get temperatures
			}
			else {
				float temperature;
				temperature = sensors.getTempCByIndex(0);	
				// Read temperature value from DHT sensor and convert from single-precision to half-precision
				Souliss_ImportAnalog(memory_map, TEMPERATURE_SLOT, &temperature);
				// Logic_Temperature(TEMPERATURE_SLOT);
				Souliss_Logic_T52(memory_map, TEMPERATURE_SLOT, 0, &data_changed);
			} 	  
			ds18b20_RequestPhase = !ds18b20_RequestPhase;
			TurnOnLED();
		} 	  
#endif
		}
} 


